package com.shouhuyun.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.shouhuyun.dao.MenuDao;
import com.shouhuyun.dao.UserDao;
import com.shouhuyun.pojo.Menu;
import com.shouhuyun.pojo.Role;
import com.shouhuyun.pojo.User;
import com.shouhuyun.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.JedisPool;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 菜单服务
 */
@Service(interfaceClass = MenuService.class)
@Transactional
public class MenuServiceImpl implements MenuService {
    @Autowired
    private MenuDao menuDao; // 查询菜单
    @Autowired
    private UserDao userDao; // 查询用户信息
    @Autowired
    private JedisPool jedisPool; // 把动态菜单存到 redis里

    // 根据用户名字查询用户 可以访问的菜单
    public List<Object> findMenuByUserName(String username) {
        /**
         * 数据分析   整体是一个大集合
         * 每一个参数是一个map
         * children是一个list
         *
         *  "path": "2",
         *  "title": "会员管理",
         *  "icon":"fa-user-md",
         *  "children": [
         *      {
         *          "path": "/2-1",
         *          "title": "会员档案",
         *          "linkUrl":"member.html",
         *          "children":[]
         *      },
         */
        // 封装菜单信息
        List<Object> menuList = new ArrayList<>();

        // 查找redis里有没有 动态菜单集合
        String menuList_redis = jedisPool.getResource().hget("menuList", username);
        if (menuList_redis != null){
            // redis里的字符串转换成list集合返回
            System.out.println("redis...");
            menuList = JSONArray.parseArray(menuList_redis);
            return menuList;
        }else {
            // 从数据库里查
            System.out.println("mysql==> redis...");

            // 1. 根据用户名字查找用户id 因为现在的名字来源于框架给的对象 所以没有id属性
            User user = userDao.findByUsername(username);
            Integer id = user.getId();

            // 2. 根据用户id查询用户所属角色
            Role role = userDao.findRoleByUserId(id);// id=1 name=系统管理员	keyword=ROLE_ADMIN description=null
            Integer roleId = role.getId();

            // 3. 根据角色id查询该角色对应的菜单id (包含了一级和二级菜单)
            List<Integer> list =  menuDao.findMenuIdByRoleId(roleId);
            // 4. 遍历集合 获取每一个菜单id
            for (Integer menuID : list) {
                // 4.1 根据菜单id查询套餐基本信息
                Menu menu = menuDao.findById(menuID);

                // 4.2 获取菜单等级
                Integer level = menu.getLevel();
                if (level == 1){
                    // 说明是一级菜单
                    Map<String,Object> map = new HashMap<>();
                    map.put("path",menu.getPath());
                    map.put("title",menu.getName());
                    map.put("icon",menu.getIcon());

                    // 存放二级菜单的 信息
                    List<Object> listChildren = new ArrayList<>();
                    // 查属于该一级菜单的二级菜单 的id
                    List<Integer> childrenIdlist = menuDao.findMenu2IdByParentId(menu.getId());
                    for (Integer childrenId : childrenIdlist) {
                        // 拿到二级菜单
                        Menu childrenMenu = menuDao.findById(childrenId);
                        // 二级菜单
                        Map<String,Object> map2 = new HashMap<>();
                        map2.put("path",childrenMenu.getPath());
                        map2.put("title",childrenMenu.getName());
                        map2.put("linkUrl",childrenMenu.getLinkUrl());
                        listChildren.add(map2);
                    }
                    map.put("children",listChildren);

                    menuList.add(map);
                }
            }

            // 5. 存到redis里
            // 5.1 修改数据格式
            Object menulist_json = JSON.toJSON(menuList);
            // 5.2 保存都redis里
            jedisPool.getResource().hset("menuList",username,menulist_json.toString());
            // 5.3 设置过期时间为一个月
            jedisPool.getResource().expire(username,60*60);
            // 6. 返回数据
            return menuList;
        }
    }

    // 查询所有菜单
    public List<Menu> findAll() {
        List<Menu> list = menuDao.findAll();
        return list;
    }
}
